package com.chat.netty.websocketserver.service;

import com.alibaba.fastjson.JSONObject;
import com.chat.netty.websocketserver.vo.GroupInfo;
import com.chat.netty.websocketserver.vo.NettyConstant;
import com.chat.netty.websocketserver.vo.NettyUserInfo;
import com.chat.netty.websocketserver.vo.ResultMsg;
import com.chat.user.service.UserService;
import com.mysql.jdbc.StringUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

@Service
public class ChatService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ChatService.class);


    public void add(ChannelHandlerContext ctx) {
        NettyConstant.getChannelGroup().add(ctx.channel());
    }



    public void remove(ChannelHandlerContext ctx) {

        for (Entry<String, ChannelHandlerContext> entry : NettyConstant.onlineUserMap.entrySet()) {
            if (entry.getValue() == ctx) {
                LOGGER.info(MessageFormat.format("正在移除握手实例...userId:{0}", entry.getKey()));
                NettyConstant.webSocketHandshakerMap.remove(ctx.channel().id().asLongText());
                LOGGER.info(MessageFormat.format("已移除握手实例，当前握手实例总数为：{0}", NettyConstant.webSocketHandshakerMap.size()));

                NettyConstant.onlineUserMap.remove(entry.getKey());
                LOGGER.info(MessageFormat.format("userId为 {0} 的断开连接，当前在线人数为：{1}", entry.getKey(), NettyConstant.onlineUserMap.size()));
                break;
            }
        }
//        Iterator<Entry<String, ChannelHandlerContext>> iterator =
//                Constant.onlineUserMap.entrySet().iterator();
//        while(iterator.hasNext()) {
//            Entry<String, ChannelHandlerContext> entry = iterator.next();
//            if (entry.getValue() == ctx) {
//                LOGGER.info("正在移除握手实例...");
//                Constant.webSocketHandshakerMap.remove(ctx.channel().id().asLongText());
//                LOGGER.info(MessageFormat.format("已移除握手实例，当前握手实例总数为：{0}"
//                        , Constant.webSocketHandshakerMap.size()));
//                iterator.remove();
//                LOGGER.info(MessageFormat.format("userId为 {0} 的断开连接，当前在线人数为：{1}"
//                        , entry.getKey(), Constant.onlineUserMap.size()));
//                break;
//            }
//        }

    }

//    public void FileMsgSingleSend(JSONObject param, ChannelHandlerContext ctx) {
//        String fromUserId = (String)param.get("fromUserId");
//        String toUserId = (String)param.get("toUserId");
//        String originalFilename = (String)param.get("originalFilename");
//        String fileSize = (String)param.get("fileSize");
//        String fileUrl = (String)param.get("fileUrl");
//        ChannelHandlerContext toUserCtx = Constant.onlineUserMap.get(toUserId);
//        if (toUserCtx == null) {
//            String responseJson = new ResponseJson()
//                    .error(MessageFormat.format("userId为 {0} 的用户没有登录！", toUserId))
//                    .toString();
//            sendMessage(ctx, responseJson);
//        } else {
//            String responseJson = new ResponseJson().success()
//                    .setData("fromUserId", fromUserId)
//                    .setData("originalFilename", originalFilename)
//                    .setData("fileSize", fileSize)
//                    .setData("fileUrl", fileUrl)
//                    .toString();
//            sendMessage(toUserCtx, responseJson);
//        }
//    }

//    public void FileMsgGroupSend(JSONObject param, ChannelHandlerContext ctx) {
//        String fromUserId = (String)param.get("fromUserId");
//        String toGroupId = (String)param.get("toGroupId");
//        String originalFilename = (String)param.get("originalFilename");
//        String fileSize = (String)param.get("fileSize");
//        String fileUrl = (String)param.get("fileUrl");
//        GroupInfo groupInfo = Constant.groupInfoMap.get(toGroupId);
//        if (groupInfo == null) {
//            String responseJson = new ResponseJson().error("该群id不存在").toString();
//            sendMessage(ctx, responseJson);
//        } else {
//            String responseJson = new ResponseJson().success()
//                    .setData("fromUserId", fromUserId)
//                    .setData("toGroupId", toGroupId)
//                    .setData("originalFilename", originalFilename)
//                    .setData("fileSize", fileSize)
//                    .setData("fileUrl", fileUrl)
//                    .toString();
//            groupInfo.getMembers().stream()
//                .forEach(member -> {
//                    ChannelHandlerContext toCtx = Constant.onlineUserMap.get(member.getUserId());
//                    if (toCtx != null && !member.getUserId().equals(fromUserId)) {
//                        sendMessage(toCtx, responseJson);
//                    }
//                });
//        }
//    }

    public void register(JSONObject param, ChannelHandlerContext ctx) { //个人注册
        String userName = (String) param.get("userName");
        String userId = (String) param.get("userId");
        NettyConstant.onlineUserMap.put(userId, ctx); //
        NettyConstant.onlineUsers.put(userId, userName); //存储在线用户

        String content = "\"用户名字为：" + userName + "\" 进入了聊天室！";

        String responseJson = new ResultMsg().ok(content, NettyConstant.onlineUsers);

        for (Entry<String, String> entry : NettyConstant.onlineUsers.entrySet()) {
            sendMessage(NettyConstant.onlineUserMap, entry.getKey(), responseJson);
        }

        LOGGER.info(MessageFormat.format("userName {0} 的用户登记到在线用户表，当前在线人数为：{1}", userName, NettyConstant.onlineUserMap.size()));
    }

    public void registerGroup(JSONObject param, ChannelHandlerContext ctx) {//群聊注册
        String userId = (String) param.get("userId");
        String userName = (String) param.get("userName");
        String groupId = (String) param.get("groupId");
        NettyConstant.onlineUserMap.put(userId, ctx);
        NettyConstant.onlineUsers.put(userId, userName); //存储在线用户

        NettyUserInfo users = new NettyUserInfo();//创建用户
        users.setId(userId);
        users.setGroupId(groupId);
        users.setOnlineUserMap(NettyConstant.onlineUserMap);
        users.setUsername(userName);

        String content = "\"用户名字为：" + userName + "\" 进入了" + groupId + "聊天室";

        GroupInfo groupInfo = NettyConstant.groupInfoMap.get(groupId);
        if (groupInfo != null) { //已存在组,仅需要添加用户
            if (groupInfo.getUsers().stream().noneMatch(x -> x.getUserId().equals(userId))) {
                groupInfo.getUsers().add(users);
            }
        } else {//不存在组,创建组
            groupInfo = new GroupInfo();
            List<NettyUserInfo> userList = new ArrayList<>();
            userList.add(users);
            groupInfo.setUsers(userList);
            NettyConstant.groupInfoMap.put(groupId, groupInfo);
        }

        List<NettyUserInfo> resultUsers = groupInfo.getUsers();

        groupInfo.getUsers().forEach(user -> {
            String responseJson = new ResultMsg().success(content, resultUsers, userName);
            sendMessage(NettyConstant.onlineUserMap, user.getUserId(), responseJson);
        });

        LOGGER.info(MessageFormat.format("userName {0} 的用户登记到在线用户表，当前在线人数为：{1}", userName, NettyConstant.onlineUserMap.size()));

        LOGGER.info(MessageFormat.format("group {0} 的组队成功人数:{1}，组队总数量为：{2}", groupId, NettyConstant.groupInfoMap.get(groupId).getUsers().size(), NettyConstant.groupInfoMap.size()));
    }

    private void sendMessage(Map<String, ChannelHandlerContext> onlineUserMap, String userId, String message) {
        ChannelHandlerContext toCtx = onlineUserMap.get(userId);
        if (toCtx != null) {
            sendMessage(toCtx, message);
        }
    }


    private void sendMessage(ChannelHandlerContext ctx, String message) {
        ctx.channel().writeAndFlush(new TextWebSocketFrame(message));
    }


    /**
     * 推送给某一用户
     *
     * @param userId 用户ID
     * @param msg    消息信息
     */
    public void pushMsgToOne(String userId, String msg) {
        sendMessage(NettyConstant.onlineUserMap, userId, msg);
    }

    /**
     * 推送给所有用户
     *
     * @param msg 消息信息
     */
    public void pushMsgToAll(String msg) {
        NettyConstant.getChannelGroup().writeAndFlush(new TextWebSocketFrame(msg));
    }


    /**
     * 推送给其他用户
     *
     * @param param
     */
    public void pushMsgToOther(JSONObject param) {
        String currentName = (String) param.get("currentName");
        String currentUserId = (String) param.get("currentUserId");
        String msg = (String) param.get("msg");
        String to = (String) param.get("to");

        String[] tos = to.substring(0, to.length() - 1).split("-");
        List<String> lists = Arrays.asList(tos);

        for (String userId : lists) {
            if (!userId.equals(currentUserId)) {
                sendMessage(NettyConstant.onlineUserMap, currentUserId, new ResultMsg().success(currentName, msg, NettyConstant.onlineUsers));
            }
        }
    }

    /**
     * 推送给全部用户
     *
     * @param param
     */
    public void pushMsgToAll(JSONObject param) {
        String msg = (String) param.get("msg");
        String type = (String) param.get("type");
        String responseJson = StringUtils.isNullOrEmpty(type)
                    ? new ResultMsg().all(msg)
                    : new ResultMsg().all(msg, type);

        pushMsgToAll(responseJson);
    }


    public void pushMsgToGroup(JSONObject param) {
        String currentUserId = (String) param.get("userId");
        String currentName = (String) param.get("userName");
        String msg = (String) param.get("msg");
        String groupId = (String) param.get("groupId");
        String to = (String) param.get("to");

        String[] tos = to.substring(0, to.length() - 1).split("-");
        List<String> lists = Arrays.asList(tos);

        GroupInfo groupInfo = NettyConstant.groupInfoMap.get(groupId);


        for (String to_userId : lists) {
            if (!to_userId.equals(currentUserId)){
                if (groupInfo != null) {
                    groupInfo.getUsers().forEach(user -> {
                        if (user.getGroupId().equals(groupId) && !currentUserId.equals(user.getUserId())) {
                            String responseJson = new ResultMsg().success(msg, groupInfo.getUsers(),currentName);
                            sendMessage(NettyConstant.onlineUserMap, user.getUserId(), responseJson);
                        }
                    });
                }
            }

        }
    }


    //    public void groupSend(JSONObject param, ChannelHandlerContext ctx) {
//
//        String fromUserId = (String)param.get("fromUserId");
//        String toGroupId = (String)param.get("toGroupId");
//        String content = (String)param.get("content");
//
//        /*String userId = (String)param.get("userId");
//        String fromUsername = (String)param.get("fromUsername");*/
//        /*String responseJson = new ResponseJson().success()
//                .setData("fromUsername", fromUsername)
//                .setData("content", content)
//                .setData("type", ChatType.GROUP_SENDING)
//                .toString();*/
//        /*Set<Entry<String, ChannelHandlerContext>> userCtxs = Constant.onlineUserMap.entrySet();
//        for (Entry<String, ChannelHandlerContext> userCtx : userCtxs) {
//            if (!userCtx.getKey().equals(userId)) {
//                sendMessage(userCtx.getValue(), responseJson);
//            }
//        }*/
//        GroupInfo groupInfo = Constant.groupInfoMap.get(toGroupId);
//        if (groupInfo == null) {
//            String responseJson = new ResponseJson().error("该群id不存在").toString();
//            sendMessage(ctx, responseJson);
//        } else {
//            String responseJson = new ResponseJson().success()
//                    .setData("fromUserId", fromUserId)
//                    .setData("content", content)
//                    .setData("toGroupId", toGroupId)
//                    .toString();
//            groupInfo.getMembers().stream()
//                .forEach(member -> {
//                    ChannelHandlerContext toCtx = Constant.onlineUserMap.get(member.getUserId());
//                    if (toCtx != null && !member.getUserId().equals(fromUserId)) {
//                        sendMessage(toCtx, responseJson);
//                    }
//                });
//        }
//    }
}
